package com.eptok.gw.szcups.pojo;

import org.dom4j.Document;
import org.dom4j.Element;

import ys8583.parse.IOMessage;

import com.eptok.gw.szcups.cups.ErrorCode;
import com.eptok.gw.szcups.util.DateUtil;

public abstract class XmlMessage {
	
	protected String ver;
	protected String merchantId;
	protected String termianlId;
	protected String sender;
	protected String msgCode;
	protected String time;
	protected String status;
	protected String reqSerialNumber;
	protected String rspSerialNumber;
	
	
	
	public String getSender() {
		return sender;
	}

	public void setSender(String sender) {
		this.sender = sender;
	}

	public String getVer() {
		return ver;
	}

	public void setVer(String ver) {
		this.ver = ver;
	}

	public String getMerchantId() {
		return merchantId;
	}

	public void setMerchantId(String merchantId) {
		this.merchantId = merchantId;
	}

	public String getTermianlId() {
		return termianlId;
	}

	public void setTermianlId(String termianlId) {
		this.termianlId = termianlId;
	}

	public String getMsgCode() {
		return msgCode;
	}

	public void setMsgCode(String msgCode) {
		this.msgCode = msgCode;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String time) {
		this.time = time;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}
	
	public String getReqSerialNumber() {
		return reqSerialNumber;
	}

	public void setReqSerialNumber(String reqSerialNumber) {
		this.reqSerialNumber = reqSerialNumber;
	}

	public String getRspSerialNumber() {
		return rspSerialNumber;
	}

	public void setRspSerialNumber(String rspSerialNumber) {
		this.rspSerialNumber = rspSerialNumber;
	}

	protected abstract void decodeBody(Document document)throws Exception;
	
	protected abstract String encodeBody(IOMessage iomessage)throws Exception;
	

	/**
	 * 解析报文
	 * @throws Exception
	 */
	public void decode(Document document)throws Exception{
		decodeHead(document);
		decodeBody(document);
	}
	
	protected void decodeHead(Document document) throws Exception{
		ver = ((Element) document.selectObject("/szcups/head/Ver")).getTextTrim();
		merchantId = ((Element) document.selectObject("/szcups/head/MerchantId")).getTextTrim();
		termianlId = ((Element) document.selectObject("/szcups/head/TermianlId")).getTextTrim();
		time = ((Element)document.selectObject("/szcups/head/Time")).getTextTrim();
		msgCode = ((Element)document.selectObject("/szcups/head/MsgCode")).getTextTrim();
		sender = ((Element)document.selectObject("/szcups/head/Sender")).getTextTrim();
	}
	
	
	public String encode(IOMessage iomessage)throws Exception{
		StringBuffer sb = new StringBuffer();
		sb.append("<?xml version=\"1.0\" encoding=\"GBK\" ?>");
		sb.append("<szcups>");
		sb.append(encodeHead());
		if(status.equals("00")){
			sb.append(encodeBody(iomessage));
		}
		sb.append("</szcups>");
		return sb.toString();
	}
	
	
	/**
	 * 解析PosData报文
	 * @throws Exception
	 */
	protected PosData decodePosData(Document document)throws Exception{
		PosData posData = new PosData();
		posData.setCardNum(((Element) document.selectObject("/szcups/body/PosData/BankAccount")).getTextTrim());
		posData.setTrack2(((Element) document.selectObject("/szcups/body/PosData/Track2Data")).getTextTrim());
		posData.setTrack3(((Element) document.selectObject("/szcups/body/PosData/Track3Data")).getTextTrim());
		posData.setPin(((Element) document.selectObject("/szcups/body/PosData/PinData")).getTextTrim());
		posData.setTpk(((Element) document.selectObject("/szcups/body/PosData/TPK")).getTextTrim());
		posData.setEntryMode(((Element) document.selectObject("/szcups/body/PosData/EntryMode")).getTextTrim());
		return posData;
	}
	
	/**
	 * 解析PosData报文
	 * @throws Exception
	 */
	protected CupsResult decodeCupsResult(Document document)throws Exception{
		CupsResult cupsResult = new CupsResult();
		cupsResult.setAcceptCode(((Element) document.selectObject("/szcups/body/CupsResult/AcceptCode")).getTextTrim());
		cupsResult.setAcceptName(((Element) document.selectObject("/szcups/body/CupsResult/AcceptName")).getTextTrim());
		cupsResult.setAcceptTermianl(((Element) document.selectObject("/szcups/body/CupsResult/AcceptTermianl")).getTextTrim());
		cupsResult.setAcquireInstitution(((Element) document.selectObject("/szcups/body/CupsResult/AcquireInstitution")).getTextTrim());
		cupsResult.setConditionCode(((Element) document.selectObject("/szcups/body/CupsResult/ConditionCode")).getTextTrim());
		cupsResult.setCurrencyCode(((Element) document.selectObject("/szcups/body/CupsResult/CurrencyCode")).getTextTrim());
		cupsResult.setCustomizingMessage(((Element) document.selectObject("/szcups/body/CupsResult/CustomizingMessage")).getTextTrim());
		cupsResult.setForwardInstitution(((Element) document.selectObject("/szcups/body/CupsResult/ForwardInstitution")).getTextTrim());
		cupsResult.setLocalDate(((Element) document.selectObject("/szcups/body/CupsResult/LocalDate")).getTextTrim());
		cupsResult.setLocalTime(((Element) document.selectObject("/szcups/body/CupsResult/LocalTime")).getTextTrim());
		cupsResult.setMessageCode(((Element) document.selectObject("/szcups/body/CupsResult/MessageCode")).getTextTrim());
		cupsResult.setProcessCode(((Element) document.selectObject("/szcups/body/CupsResult/ProcessCode")).getTextTrim());
		cupsResult.setRetrievalNumber(((Element) document.selectObject("/szcups/body/CupsResult/RetrievalNumber")).getTextTrim());
		cupsResult.setSettlement(((Element) document.selectObject("/szcups/body/CupsResult/Settlement")).getTextTrim());
		cupsResult.setSytemTrace(((Element) document.selectObject("/szcups/body/CupsResult/SytemTrace")).getTextTrim());
		cupsResult.setTransDate(((Element) document.selectObject("/szcups/body/CupsResult/TransDate")).getTextTrim());
		return cupsResult;
	}
	
	
	protected String encodeHead() throws Exception{
		StringBuffer sb = new StringBuffer();
		sb.append("<head>");
		sb.append("<Ver>").append(ver).append("</Ver>");
		sb.append("<MerchantId>").append(merchantId).append("</MerchantId>");
		sb.append("<TermianlId >").append(termianlId).append("</TermianlId>");
		sb.append("<MsgCode>").append(msgCode.replace("S", "R")).append("</MsgCode>");
		sb.append("<Time>").append(DateUtil.formatDate("yyyyMMddHHmmss")).append("</Time>");
		sb.append("<Sender>").append(sender).append("</Sender>");
		sb.append("<Status>").append(status).append("</Status>");
		sb.append("<Description>").append(ErrorCode.map.get(status)).append("</Description>");
		sb.append("</head>");
		return sb.toString();
	}
	
	protected String encodeCupsResult(IOMessage iomessage) throws Exception{
		StringBuffer sb = new StringBuffer();
		sb.append("<CupsResult>");
		sb.append("<MessageCode>").append(iomessage.getReqMessageID()).append("</MessageCode>");
		sb.append("<ProcessCode>").append(iomessage.getReqMesField(3)).append("</ProcessCode>");
		sb.append("<TransDate>").append(iomessage.getReqMesField(7)).append("</TransDate>");
		sb.append("<SytemTrace>").append(iomessage.getReqMesField(11)).append("</SytemTrace>");
		sb.append("<LocalTime>").append(iomessage.getReqMesField(12)).append("</LocalTime>");
		sb.append("<LocalDate>").append(iomessage.getReqMesField(13)).append("</LocalDate>");
		sb.append("<Settlement>").append(iomessage.getReqMesField(15)).append("</Settlement>");
		sb.append("<ConditionCode>").append(iomessage.getReqMesField(25)).append("</ConditionCode>");
		sb.append("<AcquireInstitution>").append(iomessage.getReqMesField(32)).append("</AcquireInstitution>");
		sb.append("<ForwardInstitution>").append(iomessage.getReqMesField(33)).append("</ForwardInstitution>");
		sb.append("<RetrievalNumber>").append(iomessage.getReqMesField(37)).append("</RetrievalNumber>");
		sb.append("<AcceptTermianl>").append(iomessage.getReqMesField(41)).append("</AcceptTermianl>");
		sb.append("<AcceptCode>").append(iomessage.getReqMesField(42)).append("</AcceptCode>");
		sb.append("<AcceptName>").append(iomessage.getReqMesField(43)).append("</AcceptName>");
		sb.append("<CustomizingMessage>").append(iomessage.getReqMesField(48)).append("</CustomizingMessage>");
		sb.append("<CurrencyCode>").append(iomessage.getReqMesField(49)).append("</CurrencyCode>");
		sb.append("</CupsResult>");
		return sb.toString();
	}
}
